package com.gxc.array;

/**
 * 一个 char 类型的数组 chs，其中所有的字符都不同。
 * 例如，chs=['A'，'B'，'C'，.....'Z']，则字符串与整数的对应关系如下:
 * A,B... Z,AA,AB...AZ,BA,BB...ZZ,AAA... ZZZ, AAAA...
 * 1，2...26,27，28... 52,53,54...702,703...18278, 18279.
 * 例如，chs=['A'，'B'，'C']，则字符串与整数的对应关系如下
 * A,B,C.AA,AB...CC,AAA...CCC.AAAA..
 * 1，2,3,4,5...12,13...39,40...
 * 给定一个数组 chs，实现根据对应关系完成字符串与整数相互转换的两个函数
 *
 *
 * 整数转字符串：
 * 伪 K 进制
 * chs=“ABC”，N=42，base=3，3伪进制，从低位到高位依次为：1、3、9、27、81…
 * 从 1 开始减，42 减去 1 剩下 41；41 减去 3 剩下 38；
 * 38 减去 9 剩下 29；29 减去 27 剩下 2；2 减去 81 不够减，
 * 所以我们只需要 3 伪进制的前 4 位即可，即 27、9、3、1
 * 步骤 2 剩下的数是 2 ，前四位已经使用了一次，即 42-2=40=27*1+9*1+3*1+1*1==“AAAA”。
 * 接下来看剩下的 2 最多需要几个 27 呢？
 * 最多用 0 个（2/27)，加上前面的一个，一共需要一个 27 (A)；
 * 2%27=2，2最多用 0 个 9 ，所以一共需要 1 个 9(A)；2%3=2，2最多用 0 个 3 ，
 * 所以一共需要 1 个3(A)；最后 2 可以用 2 个 1 ，加上前面的一个，一共需要 3 个 1©，所以 42=AAAC
 *
 * https://blog.csdn.net/MIC10086/article/details/111220887
 */
public class StrToNum {

    public static void main(String[] args) {
        char[] chars = new char[]{'A', 'B', 'C'};

        System.out.println(strToNum(chars, "CCB"));
        System.out.println(strToNum2(chars, "CCB"));

        System.out.println(numToStr(chars, 7));
    }

    private static int strToNum(char[] chars, String str) {
        //长度比str少以为的字符串总共有多少个
        int preSum = sum(chars.length, str.length() -1);
        int sum = 0;
        char[] chars1 = str.toCharArray();
        for (int i = 0; i < chars1.length; i++) {
            int loc = charInArray(chars1[i], chars);
            if (loc>0) sum += (int) ((loc)*Math.pow(chars.length, str.length()-i-1));
        }
        //  +1 是 str本身
        return preSum + sum + 1;
    }

    private static int strToNum2(char[] chars, String str) {
        char[] chars1 = str.toCharArray();
        int length = chars.length;
        int sum = 0;
        int base = 1;
        for (int i = chars1.length-1; i >= 0; i--) {
            sum = sum + base * (chars1[i] - 'A' + 1);
            base = base * length;
        }
        return sum;
    }

    /**
     * 数组在字符中的第几个位置
     * @param c
     * @param chars
     * @return
     */
    public static int charInArray(char c, char[] chars) {
        int loc = -1;
        for (int i = 0; i < chars.length; i++) {
            if (c == chars[i]) return i;
        }
        return loc;
    }

    /**
     *
     * @param total  数组总共有多少字符
     * @param digit  字符组成长度多少位的字符串
     * @return
     */
    public static int sum(int total, int digit) {
        int sum = 0;
        for (int i = 1; i <= digit; i++) {
            sum += Math.pow(total, i);
        }
        return sum;
    }

    /**
     * 数字转 string
     * @param chars
     * @param i
     * @return
     */
    private static String numToStr(char[] chars, int i) {
        int length = chars.length;
        //位数
        int digit = 0;
        //长度=length的组合总数
        int cur = 1;
        while (i >= cur) {
            digit++;
            i = i - cur;
            cur = cur * length;
        }
        String str = "";
        while (digit > 0) {
            digit--;
            cur = cur / length;
            str += chars[i/cur];
            i = i % cur;
        }

        return str;
    }

}
